package org.demo.handler.row;

import com.alibaba.excel.write.handler.AbstractRowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

/**
 * mergedColList定义哪些列需要合并，mergedRegionRowList定义那些列的行怎么合并。
 * 不适用需要跨列合并。
 *
 * @author yexi
 */
public class CustomMergeStrategy extends AbstractRowWriteHandler {

    /**
     * 必须是2的倍数的待合并行索引列表。单数是合并起始行，偶数是合并结束行。
     */
    private final List<Integer> mergedRegionRowList;
    /**
     * 待合并列索引列表。定义哪些列需要合并行。
     */
    private final List<Integer> mergedColList;

    /**
     * 当前已迭代至合并列表的索引
     */
    private int nowIndex = 0;

    public CustomMergeStrategy(List<Integer> mergedRegionRowList, List<Integer> mergedColList) {
        if (mergedRegionRowList == null) {
            throw new IllegalArgumentException("合并行列表为空");
        }
        if (mergedColList == null) {
            throw new IllegalArgumentException("合并列列表为空");
        }
        if (mergedRegionRowList.size() % 2 != 0) {
            throw new IllegalArgumentException("合并行列表非2的倍数");
        }
        this.mergedRegionRowList = mergedRegionRowList;
        this.mergedColList = mergedColList;
    }

    @Override
    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
                                Integer relativeRowIndex, Boolean isHead) {
        if (isHead) {
            return;
        }
        if (nowIndex < mergedRegionRowList.size()) {
            Integer rowIndex = mergedRegionRowList.get(nowIndex);
            // 如果定位到了要合并的行起始位置
            if (rowIndex.equals(relativeRowIndex)) {
                Integer lastRowIndex = mergedRegionRowList.get(nowIndex + 1);
                for (int i = 0; i < mergedColList.size(); i++) {
                    Integer col = mergedColList.get(i);
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(
                            row.getRowNum(),
                            row.getRowNum() + (lastRowIndex - rowIndex),
                            col,
                            col);
                    writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress);
                }
                nowIndex += 2;
            }
        }
    }

}
